home *** CD-ROM | disk | FTP | other *** search
- /*
- name: objects.c
-
- Various object routines
- -----------------------
-
- */
-
-
- #include <stdlib.h>
-
- #include "defs.h"
- #include "extern.h"
-
-
-
- /*****************************************************************
- *
- * Calculate the surface-normal for a given point and shape
- *
- *****************************************************************/
-
- void GetSurfaceNormal(VECTOR *SurfNorm, POINT *SurfPoint, OBJECT *Object)
- {
- PLANE *p;
- SPHERE *s;
- ELLIPSOID *e;
- TRIANGLE *t;
- BOX *b;
- DISC *d;
- CYLINDER *c;
-
- long i;
- POINT ReTransformedPoint;
- VECTOR tempv;
- double tempd;
-
- CopyPoint(&ReTransformedPoint,SurfPoint);
-
- if(Object->Transform.NumTransforms>0) { /* Retransform the surface point */
- for(i=Object->Transform.NumTransforms-1L;i>=0L;i--) {
- /* for(i=0;i<Object->Transform.NumTransforms;i++) { */
- switch(Object->Transform.Entry[i].Type) {
- case TRANSFORM_SCALE:
- ReTransformedPoint.x=ReTransformedPoint.x/Object->Transform.Entry[i].Values.x;
- ReTransformedPoint.y=ReTransformedPoint.y/Object->Transform.Entry[i].Values.y;
- ReTransformedPoint.z=ReTransformedPoint.z/Object->Transform.Entry[i].Values.z;
- break;
- case TRANSFORM_MOVE:
- ReTransformedPoint.x=ReTransformedPoint.x-Object->Transform.Entry[i].Values.x;
- ReTransformedPoint.y=ReTransformedPoint.y-Object->Transform.Entry[i].Values.y;
- ReTransformedPoint.z=ReTransformedPoint.z-Object->Transform.Entry[i].Values.z;
- break;
- case TRANSFORM_ROTATE:
- NegVector(&tempv,&Object->Transform.Entry[i].Values);
- RotatePoint(&ReTransformedPoint,&tempv);
- break;
- case TRANSFORM_NONE:
- default:
- break;
- }
- }
- }
-
- switch(Object->ShapeType) {
- case SHAPE_PLANE:
- p=(PLANE *)(Object->Shape);
- CopyVector(SurfNorm,&(p->Normal));
- break;
- case SHAPE_SPHERE:
- s=(SPHERE *)(Object->Shape);
- SurfNorm->x=ReTransformedPoint.x-s->Centre.x;
- SurfNorm->y=ReTransformedPoint.y-s->Centre.y;
- SurfNorm->z=ReTransformedPoint.z-s->Centre.z;
- break;
- case SHAPE_ELLIPSOID:
- e=(ELLIPSOID *)(Object->Shape);
- SurfNorm->x=(ReTransformedPoint.x-e->Centre.x)/(e->Radius.x*e->Radius.x);
- SurfNorm->y=(ReTransformedPoint.y-e->Centre.y)/(e->Radius.y*e->Radius.y);
- SurfNorm->z=(ReTransformedPoint.z-e->Centre.z)/(e->Radius.z*e->Radius.z);
- break;
- case SHAPE_TRIANGLE:
- t=(TRIANGLE *)(Object->Shape);
- CopyVector(SurfNorm,&(t->Plane.Normal));
- break;
- case SHAPE_BOX:
- b=(BOX *)(Object->Shape);
- if(ReTransformedPoint.x<(b->Corners[0].x+EPSILON)) /* minx */
- CopyVector(SurfNorm,&b->Planes[0].Normal);
- else if(ReTransformedPoint.x>(b->Corners[1].x-EPSILON)) /* maxx */
- CopyVector(SurfNorm,&b->Planes[1].Normal);
- else if(ReTransformedPoint.y<(b->Corners[0].y+EPSILON)) /* miny */
- CopyVector(SurfNorm,&b->Planes[2].Normal);
- else if(ReTransformedPoint.y>(b->Corners[1].y-EPSILON)) /* maxy */
- CopyVector(SurfNorm,&b->Planes[3].Normal);
- else if(ReTransformedPoint.z<(b->Corners[0].z+EPSILON)) /* minz */
- CopyVector(SurfNorm,&b->Planes[4].Normal);
- else if(ReTransformedPoint.z>(b->Corners[1].z-EPSILON)) /* maxz */
- CopyVector(SurfNorm,&b->Planes[5].Normal);
- break;
- case SHAPE_DISC:
- d=(DISC *)(Object->Shape);
- CopyVector(SurfNorm,&(d->Plane.Normal));
- break;
- case SHAPE_CYLINDER:
- c=(CYLINDER *)(Object->Shape);
- tempd=ReTransformedPoint.x*ReTransformedPoint.x+ReTransformedPoint.y*ReTransformedPoint.y;
- if(sqrt(tempd)>(c->r-EPSILON)) {
- SurfNorm->x=ReTransformedPoint.x;
- SurfNorm->y=ReTransformedPoint.y;
- SurfNorm->z=0.0;
- }
- else {
- if(ReTransformedPoint.z<(c->Ends[1].z-EPSILON))
- CopyVector(SurfNorm,&c->Discs[0].Plane.Normal);
- else CopyVector(SurfNorm,&c->Discs[1].Plane.Normal);
- }
- break;
- }
-
- if(Object->Transform.NumTransforms>0) { /* Transform the surface normal */
- /* for(i=Object->Transform.NumTransforms-1L;i>=0L;i--) { */
- for(i=0L;i<Object->Transform.NumTransforms;i++) {
- switch(Object->Transform.Entry[i].Type) {
- case TRANSFORM_SCALE:
- SurfNorm->x=SurfNorm->x/Object->Transform.Entry[i].Values.x;
- SurfNorm->y=SurfNorm->y/Object->Transform.Entry[i].Values.y;
- SurfNorm->z=SurfNorm->z/Object->Transform.Entry[i].Values.z;
- break;
- case TRANSFORM_ROTATE:
- CopyVector(&tempv,&Object->Transform.Entry[i].Values);
- RevRotateVector(SurfNorm,&tempv);
- break;
- case TRANSFORM_MOVE:
- case TRANSFORM_NONE:
- default:
- break;
- }
- }
- }
- }
-
-
-
-
- /*****************************************************************
- *
- * Free all memory occupied by object-descriptions
- *
- *****************************************************************/
-
-
- void FreeAllObjectMemory(void)
- {
- long i;
-
- if(NumObjects>0) {
- for(i=0;i<NumObjects;i++) {
- switch(ObjectArray[i]->ShapeType) {
- case SHAPE_PLANE:
- free((PLANE *)ObjectArray[i]->Shape);
- break;
- case SHAPE_SPHERE:
- free((SPHERE *)ObjectArray[i]->Shape);
- break;
- case SHAPE_ELLIPSOID:
- free((ELLIPSOID *)ObjectArray[i]->Shape);
- break;
- case SHAPE_TRIANGLE:
- free((TRIANGLE *)ObjectArray[i]->Shape);
- break;
- case SHAPE_BOX:
- free((BOX *)ObjectArray[i]->Shape);
- break;
- case SHAPE_DISC:
- free((DISC *)ObjectArray[i]->Shape);
- break;
- case SHAPE_CYLINDER:
- free((CYLINDER *)ObjectArray[i]->Shape);
- break;
- }
- free(ObjectArray[i]);
- ObjectArray[i]=NULL;
- }
- }
-
- if(NumLights>0) {
- for(i=0;i<NumLights;i++) {
- free(LightArray[i]);
- LightArray[i]=NULL;
- }
- }
- }
-
-
-
- /*****************************************************************
- *
- * Transform handling routines
- *
- *****************************************************************/
-
-
- void ClearTransform(TRANSFORM *t)
- {
- int i;
-
- t->NumTransforms=0L;
- for(i=0;i<10;i++) {
- t->Entry[i].Type=TRANSFORM_NONE;
- t->Entry[i].Values.x=t->Entry[i].Values.y=t->Entry[i].Values.z=0.0;
- }
- }
-
-
- void CopyTransform(TRANSFORM *t2, TRANSFORM *t1)
- {
- int i;
-
- t2->NumTransforms=t1->NumTransforms;
- for(i=0;i<10;i++) {
- t2->Entry[i].Type=t1->Entry[i].Type;
- CopyVector(&t2->Entry[i].Values,&t1->Entry[i].Values);
- }
- }
-
-
- void AddTransform(TRANSFORM *t2, TRANSFORM *t1)
- {
- long i,orignumtrans;
-
- orignumtrans=t2->NumTransforms;
- t2->NumTransforms+=t1->NumTransforms;
- if(t2->NumTransforms>10L) t2->NumTransforms=10L;
- for(i=orignumtrans;i<t2->NumTransforms;i++) {
- t2->Entry[i].Type=t1->Entry[i].Type;
- CopyVector(&t2->Entry[i].Values,&t1->Entry[i].Values);
- }
- }
-
-
-